Temario:
Este documento se generó a partir de un archivo .Rmd (R markdown) en el que se intercala texto y chunks de código.
Cada fracción de código se delimita con 3 apóstrofes al comienzo y al final (```).
A su vez, en el comienzo del código se debe agregar, entre llaves, una r y el nombre del chunk.
Para generar un archivo .html (u otros) con Knit, es necesario que cada fragmento de código tenga su nombre único.
Ejemplo:
\``` {r nombre_chunk_1}
código R bla bla...
\```
Por último, dentro de las llaves se pueden agregar ciertos parámetros que indican cierta configuración de ese chunk.
Ejemplo:
{r nombre_chunk1, parámetro1 = … , parámetro2 = …}
Opciones de parámetros
echo = TRUE (default) –> muestra el código en el documento
error, eval, include, message, warning, results, fig.align, entre otros… –> mirar https://rstudio.github.io/cheatsheets/html/rmarkdown.html (otros parámetros)
Dentro del chunk de código se puede agregar texto. El mismo tiene que estar precedido por #
# indica desde dónde instalar paquetes
options(repos = c(CRAN = "http://cran.rstudio.com"))
require("knitr")
## Loading required package: knitr
# para fijar el directorio
opts_knit$set(root.dir = "/Users/FR/Documents/Burocrático/DOCENCIA/MATERIAS/8_AID/2024")
# para saber en qué directorio estamos
getwd()
## [1] "/Users/FR/Documents/Burocrático/DOCENCIA/MATERIAS/8_AID/2024/clase 1"
# todo esto mismo se puede hacer desde Rstudio>Tools>Global options>General o Packages
A continuación se muestran los tipos de datos con los que pueden encontrarse al trabajar en Ciencia de Datos, y cómo se interpretan en R.
Tipos de datos
Ciertos datos pueden ser sujetos a operaciones matemáticas / lógicas como los que se muestran a continuación:
Pongamos ahora a prueba alguna de estas operaciones… En el próximo chunk se realiza, un renglón a la vez, alguna operación matemática en particular. El output de este chunk serán cada uno de los resultados al aplicar estas operaciones.
#Operaciones básicas
2+6
## [1] 8
3*4
## [1] 12
-4/5
## [1] -0.8
4^0.2
## [1] 1.319508
sqrt(9) # raíz cuadrada
## [1] 3
cos(pi) # funciones trigonométricas
## [1] -1
exp(-2) # función exponencial
## [1] 0.1353353
factorial(5) #factorial de un número
## [1] 120
log(8)
## [1] 2.079442
pi
## [1] 3.141593
round(pi,3) # redondea el valor de pi a 3 decimales
## [1] 3.142
signif(pi,2) # devuelve el valor con dos cifras significativas
## [1] 3.1
abs(-8) # devuelve el valor absoluto
## [1] 8
Una variable sería algo así como una caja etiquetada en la memoria de la computadora donde se pueden guardar diferentes tipos de información (números, texto, valores booleanos, etc., mencionados anteriormente) y luego referenciar utilizando su nombre.
En R, la asignación de variables puede realizarse con el símbolo = o con <-.
En el próximo chunk se definen algunas variables.
Las variables pueden ser valores únicos, vectores (por ejemplo un vector de 3 elementos x, y, z), matrices de números, etc… Un vector en R se define como c(x, y, z), por ej.
n = 3 # <- puede no ser global (dentro de una fc, por ejemplo)
n <- 3 # <- asignación global
vec<-c(1,2,3) # Esta opción y la siguiente son equivalentes.
c(1,2,3)->vec
vec
## [1] 1 2 3
1:5 # números del 1 al 5 orden creciente
## [1] 1 2 3 4 5
15:10 # números del 15 al 10 orden decreciente
## [1] 15 14 13 12 11 10
x <- seq(1,8) # secuencia de enteros
x
## [1] 1 2 3 4 5 6 7 8
y<-seq(1,4,0.2) # devuelve los números de 1 a 4 espaciados en 0.2
y
## [1] 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0
z<-rep(1,5) # repite el 1 cinco veces
z
## [1] 1 1 1 1 1
w<-rep(1:3,4) # repite del 1 al 3 cuatro veces
w
## [1] 1 2 3 1 2 3 1 2 3 1 2 3
q<-rep(c(1,3,7),2) # repite la concatenación dos veces
q
## [1] 1 3 7 1 3 7
m <- c(T,F,F,T) # vector que concatena valores lógicos
m
## [1] TRUE FALSE FALSE TRUE
l<-w>2 # asigna una proposición a la variable l (w mayor que 2)
w
## [1] 1 2 3 1 2 3 1 2 3 1 2 3
l # asigna valor de verdad de la proposición
## [1] FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE
p<-c(T,F,T,F)
p
## [1] TRUE FALSE TRUE FALSE
m&p # devuelve la conjunción entre componentes de vectores lógicos de igual longitud
## [1] TRUE FALSE FALSE FALSE
m|p # devuelve la disyunción entre componentes de vectores lógicos de igual longitud
## [1] TRUE FALSE TRUE TRUE
!m # devuelve la negación de cada componente
## [1] FALSE TRUE TRUE FALSE
w
## [1] 1 2 3 1 2 3 1 2 3 1 2 3
w[1] # LA PRIMERA POSICIÓN ES EL 1!! (python es 0)
## [1] 1
w[5] # devuelve la quinta componente almacenada en el vector w
## [1] 2
w[2:4] # davuelve las componentes de 2 a 4 del vector w
## [1] 2 3 1
w[c(1,4,6)] # devuelve las componentes 1, 4 y 6 del vector w
## [1] 1 1 3
w[-c(1,4,6)] # devuelve el vector w sin las componentes 1, 4 y 6
## [1] 2 3 2 1 2 3 1 2 3
sort(w)# ordena las componentes numéricas en orden creciente
## [1] 1 1 1 1 2 2 2 2 3 3 3 3
sort(w,decreasing=TRUE)# ordena las componentes numéricas en orden decreciente
## [1] 3 3 3 3 2 2 2 2 1 1 1 1
w2<-unique(w)
w2
## [1] 1 2 3
w3<-duplicated(w)
w3
## [1] FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
En el chunk anterior se asignaron vectores a ciertas variables. En los próximos se realizarán operaciones sobre ellos
u=c(3,8,2,7,3,2,1)
sort(u) # ordena la lista
## [1] 1 2 2 3 3 7 8
order(u) # devuelve el índice en la lista ordenada
## [1] 7 3 6 1 5 4 2
u==3 # operación lógica que busca las posiciones de u que guardan el 3
## [1] TRUE FALSE FALSE FALSE TRUE FALSE FALSE
u[u==3]<-4 # en esas posiciones asigna un 4
u
## [1] 4 8 2 7 4 2 1
which(u>=4) # devuelve las posiciones de u que tienen números mayores o iguales a 4
## [1] 1 2 4 5
u[which(u>=4)]<-0 # asigna 0 a esas posiciones
u
## [1] 0 0 2 0 0 2 1
rev(u) # invierte el orden de las componentes del vector
## [1] 1 2 0 0 2 0 0
veccha<-c("Alicia","Pedro","casa")
names(vec)<-veccha
vec["casa"]
## casa
## 3
order(veccha)
## [1] 1 3 2
sort(veccha)# ordena alfabéticamente las componentes del vector de caracteres
## [1] "Alicia" "casa" "Pedro"
h <- paste(c("a","b","c","d"), 2:5, sep="") # genera pares ordenados
h
## [1] "a2" "b3" "c4" "d5"
t=paste(c("a","b"), 2:6, sep=",") # genera pares ordenados separados por comas
t
## [1] "a,2" "b,3" "a,4" "b,5" "a,6"
length(w) # devuelve la longitud del vector w
## [1] 12
length(c(w,h)) # devuelve la longitud del vector w concatenado con h
## [1] 16
mode(w) # devuelve el tipo de datos del vector w, en este caso numérico
## [1] "numeric"
mode(h) # devuelve el tipo de datos del vector h, en este caso de caracteres
## [1] "character"
mode(m) # devuelve el tipo de datos del vector m, en este caso lógico
## [1] "logical"
storage.mode(y) # equivalente a mode, en este caso el tipo es "double" que significa de doble precisión
## [1] "double"
storage.mode(w) # en este caso el tipo es entero
## [1] "integer"
storage.mode(h)
## [1] "character"
storage.mode(m)
## [1] "logical"
v1<-rep(2,4)
v2<-2:5
-2*v2 # producto de un vector por un escalar
## [1] -4 -6 -8 -10
v2+3 # suma 3 a cada componente
## [1] 5 6 7 8
v1+3*v2 # combinación lineal de vectores
## [1] 8 11 14 17
v1/v2 # división componente a componente
## [1] 1.0000000 0.6666667 0.5000000 0.4000000
v1*v2 # producto componente a componente
## [1] 4 6 8 10
v1**v2 # potenciación componente a componente
## [1] 4 8 16 32
v3=2*v1-3*v2
v3
## [1] -2 -5 -8 -11
min(v3) # devuelve el valor mínimo del vector
## [1] -11
max(v3) # devuelve el valor máximo del vector
## [1] -2
sum(v3) # suma las componentes del vector
## [1] -26
cumsum(v3) # devuelve un vector que guarda en cada componente la suma de las anteriores más esa
## [1] -2 -7 -15 -26
prod(v3) # multiplica las componentes de un vector
## [1] 880
cumprod(v3)# devuelve un vector que guarda el producto acumulado
## [1] -2 10 -80 880
mean(v3) #calcula el promedio o media de los valores del vector
## [1] -6.5
median(v3)#calcula la mediana de los valores del vector
## [1] -6.5
sum(v1*v2) # producto escalar de dos vectores
## [1] 28
v1%*%v2 # producto escalar de dos vectores
## [,1]
## [1,] 28
En la siguiente porción de código vamos a ver el uso de ciertas herramientas y funciones.
Las operaciones que implican if (condicionales) y for (bucles) son fundamentales en la programación y se utilizan para controlar el flujo de ejecución de un programa. Aunque no son operaciones en el sentido tradicional de operaciones aritméticas o de manipulación de datos, desempeñan un papel crucial en la lógica y el control del programa.
La estructura if permite que el programa tome decisiones basadas en condiciones lógicas.
Ejemplo: Si se cumple la condición A, imprimi “cumplí”, sino imprimí “seguí participando”…
Los bucles for son estructuras de control que permiten repetir un bloque de código un número específico de veces. Se utilizan cuando se necesita realizar una tarea varias veces, por ejemplo, para recorrer elementos de una lista, realizar cálculos iterativos, o realizar una operación en un rango de valores. Los bucles for típicamente tienen una variable de iteración que va tomando diferentes valores en cada iteración.
Por ejemplo: Por cada elemento en la lista [1,2,3], sumá 2 veces su valor –> output: [3,6,9]
Una función es una herramienta en programación que agrupa un conjunto de acciones o pasos para realizar una tarea específica. Recibe parámetros, realiza dichos pasos y devuelve un resultado en particular.
Ejemplo sencillo: se quiere sumar 2+3, luego 3+7 y finalmente 10+24. Si uno tipea cada par de números, tendrá un output de 5, 10, o el resultado que corresponda… Si ahora se quisiese generalizar la operación de suma de 2 valores, uno podría generar una función que reciba 2 parámetros y que devuelva la suma de los mismos, de manera más general. Esto evitaría tener que repetir 3 veces la operación, y se reemplazaría con la invocación de la misma función 3 veces, c/u con un par de valores distintos.
Obviamente este ejemplo de función es súper sencillo, pero imaginense ahora que la función realiza 10 pasos! Tener una función hace que el código sea más organizado, legible y fácil de mantener (además de ahorrarnos repetir el código tantas veces como querramos que ocurran esos 10 pasos!).
#Uso de for:
MiVectorInicial<-rep(0,10)
for (i in 1:10){
MiVectorInicial[i]<-2*(i+1)
}
MiVectorInicial
## [1] 4 6 8 10 12 14 16 18 20 22
#Uso de if:
if(length(MiVectorInicial)>1){
print("Es un vector")
}else{
print("Es un escalar")}
## [1] "Es un vector"
#Ejemplo de función:
Promedio<-function(vectorNumerico){
prom<-sum(vectorNumerico)/length(vectorNumerico)
return(prom)
}
Promedio(c(1,-4,5,0,10))
## [1] 2.4
Otros tipos de variables son las matrices. Una matriz es una estructura de datos compuesta por filas y columnas (en el caso de matrices bidimensionales). En ciencia de datos suelen ser el input de muchos modelos de ML.
En R se pueden generar con la función matrix, como la concatenación de vectores, etc. Cada elemento de la matriz tiene una posición (índice) en filas y columnas. Las filas y columnas se pueden nombrar, y se existen operaciones matemáticas específicas que se pueden realizar sobre ellas. A continuación se puede ver un resumen de asignación de matrices y operaciones matemáticas asociadas.
ls() # lista todas las variables que se han creado en el espacio de trabajo
## [1] "h" "i" "l" "m"
## [5] "MiVectorInicial" "n" "p" "Promedio"
## [9] "q" "t" "u" "v1"
## [13] "v2" "v3" "vec" "veccha"
## [17] "w" "w2" "w3" "x"
## [21] "y" "z"
data=1:10
matrix(data,nrow=2,ncol=5) # acomoda los datos por columna en una matriz de nrow filas y ncol columnas
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 3 5 7 9
## [2,] 2 4 6 8 10
matrix(data,nrow=2,ncol=5,byrow=T) # # acomoda los datos por fila en una matriz de nrow filas y ncol columnas
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 2 3 4 5
## [2,] 6 7 8 9 10
matrix(c(2,4,5,6,-8,11),nrow=2) # acomoda la concatenación por columnas de acuerdo a la cantidad de filas indicada
## [,1] [,2] [,3]
## [1,] 2 5 -8
## [2,] 4 6 11
vec1=seq(2,5)
vec2=seq(-5,-2)
cbind(vec1,vec2) # devuelve la matriz que tiene a estos vectores como columnas
## vec1 vec2
## [1,] 2 -5
## [2,] 3 -4
## [3,] 4 -3
## [4,] 5 -2
rbind(vec1,vec2) # devuelve laa matriz que tiene a estos vectores como filas
## [,1] [,2] [,3] [,4]
## vec1 2 3 4 5
## vec2 -5 -4 -3 -2
mat1=matrix(data,nrow=2,ncol=5) # asigna valores a una matriz
mat1 # devuelve la matriz
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 3 5 7 9
## [2,] 2 4 6 8 10
colnames(mat1)<-c("A","B","C","D","E") # asigna nombres a las columnas de la matriz
mat1 # devuelve la matriz, ahora con nombres en sus columnas
## A B C D E
## [1,] 1 3 5 7 9
## [2,] 2 4 6 8 10
rownames(mat1)<-c("2015","2016") # asigna nombres a las filas de la matriz
mat1 # devuelve la matriz, ahora con nombres en sus filas
## A B C D E
## 2015 1 3 5 7 9
## 2016 2 4 6 8 10
dim(mat1) # devuelve la cantidad de filas y de columnas de la matriz
## [1] 2 5
storage.mode(mat1) # devuelve el tipo de valores guardados en la matriz
## [1] "integer"
mat1[1,2] # devuelve el elemento de la fila 1 y la columna 2 de la matriz
## [1] 3
mat1[1,3:5] # devuelve los elementos de la fila 1 y correspondientes a las columnas de 3 a 5
## C D E
## 5 7 9
mat1[1,] # devuelve la fila 1 de la matriz
## A B C D E
## 1 3 5 7 9
mat1[,2] # devuelve la columna 2 de la matriz
## 2015 2016
## 3 4
mat1[1,2]<--3.1 # asigna un valor dado en la fila 1 y la columna 2 de la matriz
mat1
## A B C D E
## 2015 1 -3.1 5 7 9
## 2016 2 4.0 6 8 10
storage.mode(mat1) # observar que cambió el modo de almacenamiento de la matriz
## [1] "double"
mat2<-matrix(seq(10,1),nrow=2,byrow=T) # asigna valores a una nueva matriz
mat2 # devuelve la matriz
## [,1] [,2] [,3] [,4] [,5]
## [1,] 10 9 8 7 6
## [2,] 5 4 3 2 1
t(mat2) # devuelve la matriz transpuesta de la matriz
## [,1] [,2]
## [1,] 10 5
## [2,] 9 4
## [3,] 8 3
## [4,] 7 2
## [5,] 6 1
mat1+mat2 # suma de matrices
## A B C D E
## 2015 11 5.9 13 14 15
## 2016 7 8.0 9 10 11
mat1-mat2 # resta de matrices
## A B C D E
## 2015 -9 -12.1 -3 0 3
## 2016 -3 0.0 3 6 9
mat2+3 # suma 3 a cada elemento de la matriz
## [,1] [,2] [,3] [,4] [,5]
## [1,] 13 12 11 10 9
## [2,] 8 7 6 5 4
3*mat2 # producto de matriz por escalar
## [,1] [,2] [,3] [,4] [,5]
## [1,] 30 27 24 21 18
## [2,] 15 12 9 6 3
mat1*mat2 # producto elemento a elemento
## A B C D E
## 2015 10 -27.9 40 49 54
## 2016 10 16.0 18 16 10
sqrt(mat2) # raíz cuadrada de cada elemento de la matriz
## [,1] [,2] [,3] [,4] [,5]
## [1,] 3.162278 3 2.828427 2.645751 2.44949
## [2,] 2.236068 2 1.732051 1.414214 1.00000
sqrt(mat1) # observar que cuando la operación no está definida devuelve NaN
## Warning in sqrt(mat1): NaNs produced
## A B C D E
## 2015 1.000000 NaN 2.236068 2.645751 3.000000
## 2016 1.414214 2 2.449490 2.828427 3.162278
sqrt(-9) # no está definido
## Warning in sqrt(-9): NaNs produced
## [1] NaN
mat3=mat1%*%t(mat2) # asigna a una matriz el producto de dos matrices
mat3 # devuelve el resultado del producto matricial
## [,1] [,2]
## 2015 125.1 30.6
## 2016 220.0 70.0
det(mat3) # devuelve el determinante de la matriz
## [1] 2025
solve(mat3) # devuelve la matriz inversa de la matriz
## 2015 2016
## [1,] 0.0345679 -0.01511111
## [2,] -0.1086420 0.06177778
mat3%*%solve(mat3) # devuelve el producto de una matriz por su inversa; es decir, la matriz identidad
## 2015 2016
## 2015 1 0
## 2016 0 1
crossprod(mat3,solve(mat3)) # devuelve el producto entre la traspuesta de la primera matriz y la segunda matriz
## 2015 2016
## [1,] -19.57679 11.700711
## [2,] -6.54716 3.862044
diag(mat3) # devuelve la diagonal principal de la matriz
## [1] 125.1 70.0
sum(diag(mat3)) # devuelve la traza de la matriz
## [1] 195.1
mat1
## A B C D E
## 2015 1 -3.1 5 7 9
## 2016 2 4.0 6 8 10
apply(mat1,1,sum) # devuelve la suma de cada fila de la matriz
## 2015 2016
## 18.9 30.0
apply(mat1,2,sum) # devuelve la suma de cada columna de la matriz
## A B C D E
## 3.0 0.9 11.0 15.0 19.0
apply(mat1,2,min) # devuelve el mínimo de cada columna de la matriz
## A B C D E
## 1.0 -3.1 5.0 7.0 9.0
apply(mat1,1,mean) # devuelve la media de cada fila de la matriz
## 2015 2016
## 3.78 6.00
apply(mat1,1,median) # devuelve la mediana de cada fila de la matriz
## 2015 2016
## 5 6
apply(mat1,1,var) # devuelve la varianza de cada fila de la matriz
## 2015 2016
## 23.542 10.000
apply(mat1,1,sd) # devuelve el desvío estándar de cada fila de la matriz
## 2015 2016
## 4.852010 3.162278
apply(mat1,1,summary) # devuelve un resumen de cada fila de la matriz, incluyendo valor mínimo, primer cuartil, mediana, media, tercer cuartil y valor máximo y cantidad de valores NA (Not available) si hay
## 2015 2016
## Min. -3.10 2
## 1st Qu. 1.00 4
## Median 5.00 6
## Mean 3.78 6
## 3rd Qu. 7.00 8
## Max. 9.00 10
sample(c(1,2,3), size=2, replace=FALSE)#muestra aleatoria simple a partir de un
## [1] 1 3
#vector de valores con o sin reemplazamiento
sample(1:100, size=50, replace=FALSE)# sin reemplazo
## [1] 70 39 56 46 61 43 89 65 19 79 25 60 15 20 3 71 16 23 2
## [20] 58 44 73 6 41 93 94 66 47 78 57 77 100 36 10 81 54 32 76
## [39] 97 22 75 63 28 99 87 95 67 50 51 1
# es igual que sample(100,50,FALSE)
sample(1:100, size=50, replace=TRUE)# con reemplazo
## [1] 97 88 81 11 46 65 5 91 98 29 17 93 78 99 54 46 26 41 32 7 73 76 33 86 58
## [26] 7 59 94 46 42 23 11 11 3 72 74 49 36 92 62 61 17 30 28 77 59 83 33 57 78
set.seed(111)#fijo la semilla (dura una operación)
sample(1:100, size=50, replace=TRUE)
## [1] 78 84 83 47 25 59 69 35 72 26 49 45 74 100 8 78 90 25 24
## [20] 48 59 7 21 15 1 9 63 40 25 35 71 52 100 28 38 25 61 52
## [39] 68 95 70 30 69 53 37 70 100 64 41 92
sample(c("cara","ceca"), 1, prob=c(0.3,0.7))# Ejemplo de moneda cargada
## [1] "ceca"
#(cuando el tamaño o size es 1 no hace falta el argumento replace)
Una estructura que resulta un caballito de batalla en Cs. de Datos, son los dataframes. En R, los dataframes son estructuras de datos bidimensionales que se utilizan para almacenar conjuntos de datos tabulares, donde las filas representan observaciones y las columnas representan variables/features. Los dataframes son una de las estructuras de datos más utilizadas para manipular y analizar datos. Pueden tener información de distinto tipo (int, bool, numeric, etc), y en R se pueden generar como una concatenación de vectores con la función “data.frame”.
# Ejemplo 1
Nombre = c("Ana","Luis","Pedro","Juan","Eva","Jorge") # crea un vector con los nombres
Edad = c(23,24,22,24,25,27) # crea un vector con las edades correspondientes
Sexo = as.factor(c("F",rep("M",3),"F","M")) # crea un vector como factor con el sexo correspondiente
levels(Sexo) # devuelve los grupos del vector dado como factor
## [1] "F" "M"
datos=data.frame(Nombre,Edad,Sexo) # arma un entorno de datos
datos
mean(datos$Edad[datos$Sexo=="F"]) # devuelve el promedio de la edad de las mujeres
## [1] 24
table(datos[[3]]) # devuelve una tabla de frecuencias del factor Sexo
##
## F M
## 2 4
table(datos$Sexo)
##
## F M
## 2 4
# Ejemplo 2
dfr<-data.frame("Dia"=c(1:5),"Mes"=rep("Abril",5))
dfr[,1]
## [1] 1 2 3 4 5
dfr$Mes
## [1] "Abril" "Abril" "Abril" "Abril" "Abril"
class(dfr)#devuelve la clase, es decir el tipo de objeto
## [1] "data.frame"
Otro tipo de estructura de datos común son las listas. A continuación se muestran operaciones asociadas a las mismas.
u=c(3,8,2,7,3,2,1)
u[u==3]<-4 # en esas posiciones asigna un 4 (cuando u ==3)
u[which(u>=4)]<-0 # asigna 0 a esas posiciones
u
## [1] 0 0 2 0 0 2 1
class(u) # para saber qué tipo de datos es
## [1] "numeric"
data=1:10
mat1=matrix(data,nrow=2,ncol=5) # asigna valores a una matriz
colnames(mat1)<-c("A","B","C","D","E") # asigna nombres a las columnas de la matriz
rownames(mat1)<-c("2015","2016") # asigna nombres a las filas de la matriz
mat2<-matrix(seq(10,1),nrow=2,byrow=T)
mat3=mat1%*%t(mat2)
mat3
## [,1] [,2]
## 2015 180 55
## 2016 220 70
vec1=seq(2,5)
milista<-list(c(T,F),dfr,u,"curso R",mat3) # genera una lista de objetos
milista # devuelve la lista creada
## [[1]]
## [1] TRUE FALSE
##
## [[2]]
## Dia Mes
## 1 1 Abril
## 2 2 Abril
## 3 3 Abril
## 4 4 Abril
## 5 5 Abril
##
## [[3]]
## [1] 0 0 2 0 0 2 1
##
## [[4]]
## [1] "curso R"
##
## [[5]]
## [,1] [,2]
## 2015 180 55
## 2016 220 70
names(milista)<-c("valores de verdad","df","vector u","título","matriz 3") # asigna nombres a los elementos de la lista
milista # devuelve la lista con nombres
## $`valores de verdad`
## [1] TRUE FALSE
##
## $df
## Dia Mes
## 1 1 Abril
## 2 2 Abril
## 3 3 Abril
## 4 4 Abril
## 5 5 Abril
##
## $`vector u`
## [1] 0 0 2 0 0 2 1
##
## $título
## [1] "curso R"
##
## $`matriz 3`
## [,1] [,2]
## 2015 180 55
## 2016 220 70
milista2=list("a"=3,"b"=mat3,"c"=vec1) # genera otra lista
milista2 # devuelve la otra lista
## $a
## [1] 3
##
## $b
## [,1] [,2]
## 2015 180 55
## 2016 220 70
##
## $c
## [1] 2 3 4 5
class(milista2)#devuelve la clase, es decir el tipo de objeto
## [1] "list"
names(milista)
## [1] "valores de verdad" "df" "vector u"
## [4] "título" "matriz 3"
milista$título # devuelve el elemento guardado según el nombre
## [1] "curso R"
milista[[2]] # devuelve el elemento guardado según la posición
length(milista) # devuelve la cantidad de elementos de la lista
## [1] 5
milista$a<-7 # agrega una componente al final de la lista
milista # devuelve la lista modificada
## $`valores de verdad`
## [1] TRUE FALSE
##
## $df
## Dia Mes
## 1 1 Abril
## 2 2 Abril
## 3 3 Abril
## 4 4 Abril
## 5 5 Abril
##
## $`vector u`
## [1] 0 0 2 0 0 2 1
##
## $título
## [1] "curso R"
##
## $`matriz 3`
## [,1] [,2]
## 2015 180 55
## 2016 220 70
##
## $a
## [1] 7
milista[[2]]<-mat1 # reasigna un valor de una componente según la posición
milista # devuelve la lista modificada
## $`valores de verdad`
## [1] TRUE FALSE
##
## $df
## A B C D E
## 2015 1 3 5 7 9
## 2016 2 4 6 8 10
##
## $`vector u`
## [1] 0 0 2 0 0 2 1
##
## $título
## [1] "curso R"
##
## $`matriz 3`
## [,1] [,2]
## 2015 180 55
## 2016 220 70
##
## $a
## [1] 7
split(datos,Sexo) # particiona un entorno de datos a partir del factor Sexo
## $F
## Nombre Edad Sexo
## 1 Ana 23 F
## 5 Eva 25 F
##
## $M
## Nombre Edad Sexo
## 2 Luis 24 M
## 3 Pedro 22 M
## 4 Juan 24 M
## 6 Jorge 27 M
datos2=data.frame(datos,"Nación"=as.factor(c(rep("arg",3),rep("per",3)))) # agrega información al entorno de datos
datosmujeres=split(datos2,datos2$Sexo)[[1]] # almacena los datos correspondientes a la partición por mujeres
split(datosmujeres,datosmujeres$Nación) # particiona los nuevos datos por el factor Nación; es decir, se ha particionado un dataframe por dos factores
## $arg
## Nombre Edad Sexo Nación
## 1 Ana 23 F arg
##
## $per
## Nombre Edad Sexo Nación
## 5 Eva 25 F per
De manera introductoria, ya mencionamos algunas de las herramientas básicas de R (cómo asignar variables, qué tipos de datos/estructuras pueden contener y cómo operar con ellas).
Dentro del set de herramientas básicas, vamos a presentar brevemente cómo generar muestras de distribuciones conocidas (nos puede servir para generar hipótesis y contrastarlas, etc).
# Generación de muestras de distribuciones conocidas
muestra.unif1=runif(100) # genera una muestra uniforme en [0,1] de 100 datos
muestra.unif1 # devuelve la muestra generada
## [1] 0.4563152066 0.0965785654 0.8055401752 0.0009253006 0.4667440471
## [6] 0.1732608730 0.2592225648 0.9192820815 0.2319295844 0.0525656715
## [11] 0.3043926249 0.0117258150 0.3007076983 0.8775839461 0.6652787277
## [16] 0.4537648347 0.0533223320 0.6309068091 0.4421851884 0.2673464869
## [21] 0.9837744189 0.0951241532 0.7859691235 0.1198521818 0.8812154671
## [26] 0.1310980669 0.4003378763 0.0866140136 0.3747997992 0.6847860171
## [31] 0.7347726757 0.7709477365 0.5799853499 0.5110989846 0.8529837073
## [36] 0.6298211562 0.5790059080 0.7402492894 0.3871497631 0.9935344572
## [41] 0.3980894811 0.9750010339 0.8244822009 0.5759970602 0.1362155876
## [46] 0.9397339805 0.1762847272 0.8197052260 0.0121183777 0.6400623205
## [51] 0.2670286722 0.5694977508 0.9653025323 0.1984229437 0.6928534785
## [56] 0.8360201151 0.9039043379 0.9645305418 0.6576919304 0.5489127152
## [61] 0.8850261893 0.4483733948 0.7433389057 0.4143268145 0.6807554641
## [66] 0.9259784352 0.6335980301 0.6589905838 0.4785866372 0.8188303334
## [71] 0.9639464633 0.9236928816 0.1643849264 0.3514933106 0.6171195072
## [76] 0.5801617010 0.9418052060 0.2100640042 0.0388290430 0.6158633258
## [81] 0.5146196210 0.9199719771 0.4554383077 0.8470272932 0.8706397039
## [86] 0.6830077136 0.7814433970 0.2513236194 0.0464566061 0.5632578691
## [91] 0.2937375917 0.3509654081 0.0791809296 0.8253022840 0.2642138884
## [96] 0.2638462810 0.0903810160 0.4608446269 0.6915760476 0.8489604222
muestra.unif2=runif(200,min=2,max=5) # genera una muestra uniforme en [2,5] de 200 datos
muestra.unif2 # devuelve la muestra generada
## [1] 2.738344 3.952763 4.040586 2.313604 2.335957 2.646964 2.390349 3.999001
## [9] 3.463324 3.059911 4.841032 2.335847 3.691609 4.544977 3.535304 3.999640
## [17] 2.079529 2.319381 4.086326 2.820034 4.234909 4.236186 2.500198 4.939563
## [25] 3.784276 4.064657 2.515574 2.125049 2.569550 4.284265 3.678420 3.516543
## [33] 4.918416 2.241802 3.671733 4.688022 2.323691 3.347844 2.926433 2.698648
## [41] 4.484200 2.338635 4.652007 4.176860 4.761000 2.368872 4.853431 4.009109
## [49] 2.255290 3.743470 2.637540 2.726658 3.608878 2.531181 3.711210 2.466245
## [57] 3.423258 4.182219 4.538912 4.875729 3.376495 3.089676 4.809114 4.654316
## [65] 4.011900 4.541177 4.578952 3.444636 2.951184 4.751612 3.514090 2.042216
## [73] 3.786720 3.347749 3.617600 2.281760 4.252846 2.230398 4.787092 4.431257
## [81] 4.283978 3.959619 4.820351 4.263695 2.252592 4.972120 2.809963 2.465089
## [89] 3.452566 3.843397 2.242095 4.823740 2.609627 2.595394 2.587387 4.723564
## [97] 3.599867 4.050006 3.620580 3.720452 4.540171 3.799939 2.694522 4.985696
## [105] 4.408957 4.575999 4.870954 2.165431 2.204297 3.395306 2.970486 3.922590
## [113] 2.031826 2.568321 4.316002 2.001334 2.051571 2.960197 3.588272 4.000887
## [121] 3.175444 2.818776 2.864465 4.249959 3.555529 4.212758 3.693291 2.809844
## [129] 4.622792 3.982668 2.714095 4.429550 2.705414 3.525320 4.764048 4.894645
## [137] 2.385023 2.976800 4.416626 3.350638 3.088166 4.335200 4.424530 3.390619
## [145] 3.442533 2.091332 4.367063 2.759880 3.842274 3.741781 4.798486 2.014212
## [153] 3.965617 3.387981 3.901889 3.003719 4.677798 4.013329 4.574410 2.352364
## [161] 2.774954 4.203446 3.898801 3.923576 3.068016 2.954362 2.411176 4.482930
## [169] 2.890741 4.452916 4.681564 4.044368 3.360106 3.954640 4.178277 4.097432
## [177] 3.651230 4.451367 2.809876 4.865396 4.719925 2.564771 3.699639 4.412410
## [185] 2.765824 3.708313 2.887825 3.035387 3.021521 3.825259 3.699658 2.306812
## [193] 2.976589 3.487935 2.323850 4.229754 4.083367 3.617792 3.600306 4.449906
muestra.norm.est=rnorm(30) # genera una muestra normal estándar de 30 datos
muestra.norm.est # devuelve la muestra generada
## [1] 1.00113068 -1.36329721 -0.55267543 -0.36105149 -0.05035866 0.69575937
## [7] -1.64801078 -0.49417064 -0.42734418 0.69134304 0.95476227 -1.31073488
## [13] 0.75625934 -0.53306636 -0.62069535 0.16720599 0.91288240 0.02165771
## [19] -1.11047111 1.00286196 -2.02004029 0.10304663 -0.90840858 -1.06351619
## [25] -1.28515384 -0.12684900 0.70438137 0.24808157 0.11958214 -2.44876247
muestra.norm=rnorm(50,mean=10,sd=3) # genera una muestra normal(10,3) de 50 datos
muestra.norm # devuelve la muestra generada
## [1] 2.132330 14.388036 5.208763 10.919952 13.274108 11.255454 9.646069
## [8] 9.952064 9.618192 10.139623 12.015294 8.151240 13.147651 11.924800
## [15] 7.391222 12.110211 11.764587 7.248949 7.158901 10.539778 9.522045
## [22] 9.741969 11.463944 14.764762 13.964255 10.211990 11.183020 8.495804
## [29] 9.470452 8.550878 9.160405 9.069173 9.537197 12.010516 12.585330
## [36] 8.187165 11.155229 12.480704 12.556729 10.216320 10.357967 9.947280
## [43] 12.567443 8.321192 13.005905 15.026937 6.513229 7.354157 12.523046
## [50] 8.107595
muestra.gamma=rgamma(40,rate=2, shape=3) # genera una muestra gamma(2,3) de 40 datos
muestra.gamma # devuelve la muestra generada
## [1] 1.3607154 2.8625052 0.7082220 0.6526722 0.8831231 1.2382458 1.5880699
## [8] 4.1179891 1.0224936 0.7125049 0.6341743 3.9510987 1.4472136 1.6493235
## [15] 1.1243501 0.7939093 1.4410105 1.1920454 2.7299576 0.7831665 1.5449518
## [22] 1.1387384 1.3657157 1.5539527 1.0975294 2.1197771 0.8035774 1.7196848
## [29] 1.2163229 1.6654298 1.3984546 1.3286350 2.6744641 1.1641213 1.2295824
## [36] 0.8497648 1.5634260 1.7313188 1.2485563 2.8604758
muestra.f=rf(80,df1=5,df2=6) # genera una muestra F de Snedekor(5,6) de 80 datos
muestra.f # devuelve la muestra generada
## [1] 1.79179054 0.67355964 2.96322114 0.69176692 0.35808891 2.20210401
## [7] 0.24604576 6.15235982 0.79771378 1.31972813 2.27409192 1.57489976
## [13] 0.93530317 0.70476205 1.81408545 3.39542437 1.47219174 0.53535009
## [19] 1.77939491 4.58833509 3.35254576 0.89379195 0.54818573 2.08131743
## [25] 1.61200031 6.27084196 0.79516355 2.00328152 0.50241479 1.16192890
## [31] 0.05424631 0.56930857 2.49804481 0.70608563 3.41273072 0.33935744
## [37] 0.18416724 0.27770509 4.69957523 1.57779375 3.71810675 0.68304957
## [43] 3.70268869 1.83643802 1.43615114 0.82123717 0.49643889 3.52532895
## [49] 1.21545884 0.70315944 0.95287179 0.94986284 1.47587588 5.81661215
## [55] 0.97651167 3.93430940 0.82994604 0.36532302 1.14177014 1.76066285
## [61] 1.82307842 0.90827387 0.41213196 0.62641145 6.82701360 0.29036796
## [67] 0.34432603 0.93211551 0.86234483 0.97730067 0.16429301 1.33168425
## [73] 0.96542482 0.65742963 1.05040963 5.72142269 0.77775820 0.98411002
## [79] 0.94711669 1.35420868
muestra.exp=rexp(90,2) # genera una muestra exponencial(2) de 90 datos
muestra.exp # devuelve la muestra generada
## [1] 1.45801724 1.39688747 0.64001926 0.05985939 0.52129614 0.21650448
## [7] 1.65023809 1.18084766 0.47666028 0.08409354 0.13314716 0.10863302
## [13] 0.25718151 0.60671244 0.15346392 0.07489467 0.17646005 0.18959035
## [19] 0.68971634 0.49421389 0.16808848 0.80745348 0.50735981 0.60397688
## [25] 0.95035639 0.06664926 0.48036124 1.11240490 0.40618664 0.97318411
## [31] 2.02083536 0.22433424 0.28598836 0.35046710 2.28977617 0.25327880
## [37] 0.45969774 0.09622908 0.11016080 0.49093482 0.04819430 0.43104531
## [43] 0.51441568 2.02751526 0.06740122 1.45340973 0.22976533 1.31165070
## [49] 0.37278301 0.17015795 0.43688020 0.68831041 0.21816001 1.04620092
## [55] 0.58331183 0.23845529 0.36443587 0.08531936 0.32322277 0.52904325
## [61] 0.27860913 0.21097329 1.53342343 0.96525901 0.30566505 0.42079121
## [67] 0.66089140 0.22825054 0.02858051 1.04466401 0.42983381 0.02121010
## [73] 1.15521840 0.75961818 0.67745686 1.23897988 0.13813427 0.09799302
## [79] 0.72225400 0.13006547 0.66098343 0.06215037 1.58528820 0.11021830
## [85] 0.04623547 0.09834405 0.62325048 1.16489530 0.68376060 0.03309326
muestra.chi=rchisq(70,df=4) # genera una muestra chi cuadrado con 4 grados de libertad de 70 datos
muestra.chi # devuelve la muestra generada
## [1] 0.18315538 4.10988219 2.76626062 9.92807795 7.11432209 1.92313281
## [7] 1.55811133 3.85494824 1.11740682 2.58917062 3.46546068 2.02710447
## [13] 0.61666963 7.10830382 0.57316172 3.24015933 8.69513023 9.53682857
## [19] 1.48957843 1.25615221 5.15279184 7.84013827 8.55306038 2.70598067
## [25] 4.81039660 0.85748786 0.73038847 4.30182250 0.52848094 3.31488283
## [31] 0.07152873 1.97903023 9.72174435 1.31384903 3.39297301 6.11813556
## [37] 2.24710963 0.18885686 2.09371067 3.12078043 2.48981081 1.84350149
## [43] 1.97829173 6.16320232 7.76574303 3.77170748 2.74306513 3.25853167
## [49] 5.17445897 5.78742505 1.93375425 2.43922086 5.72099940 3.09736316
## [55] 4.53168686 2.77402613 6.42272691 2.29341355 0.97083908 7.08144078
## [61] 1.24329664 2.13509825 0.92755985 2.72800253 3.90904161 0.96829884
## [67] 7.13831915 4.14887061 2.79251352 3.44967586
A continuación vamos a mencionar algunas de las funciones que se pueden aplicar sobre dataframes.
# Cargo la base:
PACIENTE<-1:30
EDAD<-c(7, 7, 8, 7, 7, 10,7 ,7, 7 ,9, 9, 11, 7, 9, 9, 11, 12, 7, 11, 6, 8, 8, 7, 10, 7, 8, 10, 7, 9, 10)
SEXO<-c("M", "M", "M", "F", "M", "M" ,"M", "M", "M", "M", "M", "F", "M" ,"M" ,"F" ,"M", "M" ,"M" ,"M" ,"F" ,"F" ,"F", "F","F", "M" ,"M" ,"F", "F" ,"F" ,"M")
PESO<-c(24.4, 23.6, 47.0, 24.0, 23.9, 41.0, 32.9, 22.4, 28.7, 31.4, 28.9, 51.2, 26.2, 58.5, 23.7, 25.5, 49.7, 39.6,42.5, 21.6, 38.0, 26.6, 20.4, 23.7, 21.4, 45.7, 51.3, 28.0, 26.9, 43.9)
TALLA<-c(1.2, 1.2, 1.4, 1.2, 1.2, 1.4, 1.3, 1.2, 1.3, 1.3, 1.3, 1.6, 1.3, 1.5, 1.3, 1.3, 1.7, 1.3, 1.5, 1.2, 1.3, 1.2, 1.2,1.3, 1.2, 1.4, 1.5, 1.3, 1.3, 1.5)
IMC<-c(16.94444, 16.38889, 23.97959, 16.66667, 16.59722, 20.91837, 19.46746, 15.55556, 16.98225, 18.57988,17.10059, 20.00000, 15.50296, 26.00000, 14.02367, 15.08876, 17.19723, 23.43195, 18.88889, 15.00000,22.48521, 18.47222, 14.16667, 14.02367, 14.86111, 23.31633, 22.80000, 16.56805, 15.91716, 19.51111)
PIMC<-c(7.97, 72.72, 97.08, 83.88, 45.85, 87.33, 96.57, 32.88, 80.77, 92.72, 55.54, 77.77, 70.70, 98.69, 3.25,2.07, 38.08, 98.75, 80.60, 39.97, 96.07, 71.06, 3.44, 2.02, 56.86, 98.99, 90.84, 57.50, 44.77, 84.89)
CC<-c(54, 52, 76, 63, 56, 78, 69, 52, 60, 69, 60, 75, 50, 88, 58, 73, 75, 76, 72, 52, 76, 54, 52, 56, 56, 78, 76, 57, 57, 76)
CatPeso<-c("N", "N", "OB", "N", "N", "SO", "OB", "N", "N", "SO", "N", "N", "N", "OB", "D", "D", "N", "OB","N" , "N", "OB", "N", "D", "D", "N", "OB", "SO", "N", "N", "N" )
IMCin<-data.frame(PACIENTE,EDAD,SEXO,PESO,TALLA,IMC,PIMC,CC,CatPeso)
#View(IMCin)
head(IMCin) # muestra las seis primeras filas de datos y los nombres de las columnas
tail(IMCin)# muestra las seis últimas filas de datos y los nombres de las columnas
dim(IMCin)#30 9
## [1] 30 9
rbind(head(IMCin),tail(IMCin))#une filas: las seis primeras filas con las seis últimas
cbind(IMCin$SEXO[1:5],IMCin$PESO[1:5]) #cuidado!
## [,1] [,2]
## [1,] "M" "24.4"
## [2,] "M" "23.6"
## [3,] "M" "47"
## [4,] "F" "24"
## [5,] "M" "23.9"
data.frame(IMCin$SEXO[1:5],IMCin$PESO[1:5]) #une columnas con sus 5 primeros elementos
table(IMCin$SEXO) # devuelve las frecuencias absolutas de las categorías de la variable
##
## F M
## 11 19
dist.conj=table(IMCin$CatPeso, IMCin$SEXO) # devuelve la distribución conjunta de las variables categoría de peso y sexo
Z= IMCin$TALLA*100 # guarda los datos de la talla en centímetros
mean(Z) # calcula la media
## [1] 133
median(Z) # calcula la mediana
## [1] 130
quantile(Z, 0.75) # calcula el cualtil 75
## 75%
## 140
quantile(Z, probs = seq(0, 1, 0.25)) # calcula los cuantiles 0, 25, 50, 75 y 100
## 0% 25% 50% 75% 100%
## 120 120 130 140 170
is.na(Z) # indica los valores que faltan
## [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE FALSE FALSE FALSE FALSE
W<-Z
W[1]<-NA # asigna un valor perdido en la primera componente del vector W
is.na(W)
## [1] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE FALSE FALSE FALSE FALSE
mean(W) # devuelve NA
## [1] NA
mean(W,na.rm=T) # no considera los valores no disponibles
## [1] 133.4483
mean(na.omit(W)) # equivalente al anterior
## [1] 133.4483
median(W,na.rm=T) # otra funcion que requiere excluir los valores no disponibles
## [1] 130
sd(W,na.rm=T) # otra funcion que requiere excluir los valores no disponibles
## [1] 13.16811
Dejamos ejercicios resultos para quienes están interactuando con R por primera vez.
Ejercicio 1 Calcular la media y mediana del vector x y el número de valores que están por debajo de la media y de la mediana, siendo x: x<-c(1,5,7,9,3,5,6,2,4,7,5,6,9,8,6,2,6,1,4).
Ejercicio 2 Escribir la función que calcula el módulo de un número real.
Ejercicio 3 Usar for para hallar el resultado de dividir de manera consecutiva el número 1111 por los siguientes divisores (en este orden): 2, 3, 4, 5, 6.
Ejercicio 4 Escribir una función que responda el signo del producto de dos factores dado, es decir “Positivo”, o “Negativo”, y en el caso que el producto sea 0 devuelva “Nulo”.
Ejercicio 5 Simular el lanzamiento de un dado.
Ejercicio 6 Simular el lanzamiento de cuatro dados o de un mismo dado cuatro veces.
Ejercicio 7 Supongamos una urna con 3 bolas blancas y 7 negras, simular la extracción de una bola (asignar, por ejemplo, el 1 a bola blanca y 0 a negra).
Ejercicio 8 Simular 8 extracciones con reemplazamiento de la urna del ejercicio 7.
Ejercicio 9 Calcular las frecuencias porcentuales de la variable sexo.
Ejercicio 10 Calcular la distribución porcentual de la variable categoría peso por sexo.
x=c(1,5,7,9,3,5,6,2,4,7,5,6,9,8,6,2,6,1,4)
m=mean(x) #calcula la media de los valores del vector
M=median(x) #calcula la mediana de los valores del vector
sum(x<m) #calcula cuántos valores quedan por debajo de la media m
sum(x<M) #calcula cuántos valores quedan por debajo de la mediana M
OPCION 1
modulo<-function(x){
if(x>=0){
return(x)
}
else{
return(-x)
}
}
OPCION 2
modu = function(x) {
y = abs(x)
return(y) }
cocientes=rep(0,5) # inicializo el vector de cocientes en cero
y = 1111
for (i in 2:6){
y = y/i
cocientes[i-1]=y
}
print(cocientes)
Definimos la función signo
signo = function(x,y) {
z = x*y
res = ifelse(z==0,“Nulo”,ifelse(z>0,“positivo”,“negativo”))
return(res) }
signo(0,-2)
sample(c(1,2,3,4,5,6), size=1)
sample(c(1,2,3,4,5,6), size=4, replace=TRUE)
sample(c(0,1), size=1, prob=c(0.3,0.7))
sample(c(0,1), size=8, replace=TRUE, prob=c(0.3,0.7))
Cargo la base:
PACIENTE<-1:30
EDAD <- c(7, 7, 8, 7, 7, 10,7 ,7, 7 ,9, 9, 11, 7, 9, 9, 11, 12, 7, 11, 6, 8, 8, 7, 10, 7, 8, 10, 7, 9, 10)
SEXO <- c(“M”, “M”, “M”, “F”, “M”, “M” ,“M”, “M”, “M”, “M”, “M”, “F”, “M” ,“M” ,“F” ,“M”, “M” ,“M” ,“M” ,“F” ,“F” ,“F”, “F”,“F”, “M” ,“M” ,“F”, “F” ,“F” ,“M”)
PESO <- c(24.4, 23.6, 47.0, 24.0, 23.9, 41.0, 32.9, 22.4, 28.7, 31.4, 28.9, 51.2, 26.2, 58.5, 23.7, 25.5, 49.7, 39.6,42.5, 21.6, 38.0, 26.6, 20.4, 23.7, 21.4, 45.7, 51.3, 28.0, 26.9, 43.9)
TALLA <- c(1.2, 1.2, 1.4, 1.2, 1.2, 1.4, 1.3, 1.2, 1.3, 1.3, 1.3, 1.6, 1.3, 1.5, 1.3, 1.3, 1.7, 1.3, 1.5, 1.2, 1.3, 1.2, 1.2,1.3, 1.2, 1.4, 1.5, 1.3, 1.3, 1.5)
IMC <- c(16.94444, 16.38889, 23.97959, 16.66667, 16.59722, 20.91837, 19.46746, 15.55556, 16.98225, 18.57988,17.10059, 20.00000, 15.50296, 26.00000, 14.02367, 15.08876, 17.19723, 23.43195, 18.88889, 15.00000,22.48521, 18.47222, 14.16667, 14.02367, 14.86111, 23.31633, 22.80000, 16.56805, 15.91716, 19.51111)
PIMC <- c(7.97, 72.72, 97.08, 83.88, 45.85, 87.33, 96.57, 32.88, 80.77, 92.72, 55.54, 77.77, 70.70, 98.69, 3.25,2.07, 38.08, 98.75, 80.60, 39.97, 96.07, 71.06, 3.44, 2.02, 56.86, 98.99, 90.84, 57.50, 44.77, 84.89)
CC <- c(54, 52, 76, 63, 56, 78, 69, 52, 60, 69, 60, 75, 50, 88, 58, 73, 75, 76, 72, 52, 76, 54, 52, 56, 56, 78, 76, 57, 57, 76)
CatPeso <- c(“N”, “N”, “OB”, “N”, “N”, “SO”, “OB”, “N”, “N”, “SO”, “N”, “N”, “N”, “OB”, “D”, “D”, “N”, “OB”,“N” , “N”, “OB”, “N”, “D”, “D”, “N”, “OB”, “SO”, “N”, “N”, “N” )
IMCin <- data.frame(PACIENTE,EDAD,SEXO,PESO,TALLA,IMC,PIMC,CC,CatPeso)
combina las dos frecuencias en una salida
sal.sexo=rbind(table(IMCin\(SEXO),100*table(IMCin\)SEXO)/length(IMCin$SEXO))
asigna nombre a las filas de la salida
rownames(sal.sexo)=c(“frec.abs”,“frec.porc”)
asigna nombre a las columnas de la salida
colnames(sal.sexo)=c(“Femenino”, “Masculino”)
muestra la salida
round(sal.sexo,2)
devuelve la distribución conjunta de las variables categoría de peso y sexo
dist_conj <- table(IMCin\(CatPeso, IMCin\)SEXO)
calculo los totales por sexo
total <- apply(dist_conj,2,sum)
calcula la distribución porcentual por sexo
dist_porc <- round(100*cbind(dist_conj[,1]/total[1],dist_conj[,2]/total[2]),2)
asigna nombre a las columnas de la distribución porcentual
colnames(dist_porc) <-c (“F(%)”,“M(%)”)
combina ambas distribuciones
sal_conj <- cbind(dist_conj,dist_porc)
calcula el total de cada columna
Totales <- apply(sal_conj,2,sum)
agrega una fila con los totales
sal_fin <- rbind(sal_conj,Totales)
muestra la salida
sal_fin
La visualización de la información es MEGA importante para la ciencia de datos. No sólo para la comunicación de los resultados, sino para una inspección visual rápida de distribuciones, outliers, etc.
Existen varios métodos que se utilizan en R para realizar lindos gráficos, que vamos a ir viendo a medida que avance el curso de AID. Básicamente se trata de los siguientes:
(R base, lattice, ggplot, plotly)
R disponibiliza bases de datos (airquality, iris, titanic, etc) que ya están integradas
Vamos a utilizar la base de datos de airquality para empezar a graficar de a una variable a la vez.
# Cargo la base de datos
data(airquality)
# Inspección rápida
str(airquality)
## 'data.frame': 153 obs. of 6 variables:
## $ Ozone : int 41 36 12 18 NA 28 23 19 8 NA ...
## $ Solar.R: int 190 118 149 313 NA NA 299 99 19 194 ...
## $ Wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...
## $ Temp : int 67 72 74 62 56 66 65 59 61 69 ...
## $ Month : int 5 5 5 5 5 5 5 5 5 5 ...
## $ Day : int 1 2 3 4 5 6 7 8 9 10 ...
# Estadística descriptiva
summary(airquality)
## Ozone Solar.R Wind Temp
## Min. : 1.00 Min. : 7.0 Min. : 1.700 Min. :56.00
## 1st Qu.: 18.00 1st Qu.:115.8 1st Qu.: 7.400 1st Qu.:72.00
## Median : 31.50 Median :205.0 Median : 9.700 Median :79.00
## Mean : 42.13 Mean :185.9 Mean : 9.958 Mean :77.88
## 3rd Qu.: 63.25 3rd Qu.:258.8 3rd Qu.:11.500 3rd Qu.:85.00
## Max. :168.00 Max. :334.0 Max. :20.700 Max. :97.00
## NA's :37 NA's :7
## Month Day
## Min. :5.000 Min. : 1.0
## 1st Qu.:6.000 1st Qu.: 8.0
## Median :7.000 Median :16.0
## Mean :6.993 Mean :15.8
## 3rd Qu.:8.000 3rd Qu.:23.0
## Max. :9.000 Max. :31.0
##
# Vista de las primeras 4 filas
head(airquality,4) # 6 por default
# Carga de bd alojada en directorio local
# nombre_variable_bd = read.csv('path_donde_está_bd/bd.csv',header=TRUE, sep=",")
En los siguientes chunks se genera código para representar distintos tipos de gráfico, en R base (lo más sencillo posible, aunque también lo más feo). En próximas clases utilizaremos ggplot, principalmente.
plot(airquality$Ozone) # sinónimo de plot(airquality[['Ozone']]) - 2 maneras de acceder a la columna
plot(airquality$Ozone, type= "b")
plot(airquality$Ozone, type= "h")
plot(airquality$Ozone, xlab = 'Concentración ozono', ylab = 'No de instancias', main = 'Niveles de Ozono en NY', col = 'blue')
# Grafico dos variables
plot(airquality$Ozone, xlab = 'Concentración', ylab = 'No de instancias', main = 'Niveles de Ozono/Radiación en NY', col = 'darkblue')
points(airquality$Solar.R/20, col = 'red') # puse radiación solar dividido 20 sólo con fines ilustrativos! ¿por qué querríamos graficar los datos transformados?
legend(130,140,c("Ozono","Radiación solar"),cex=0.7,pch=16,col=c('darkblue','red'),box.lty=0)
PLANO
frec_catmonth<-table(airquality$Month) # construye la distribución de frecuencias
pie(frec_catmonth)
pie(frec_catmonth, col=rainbow(25, alpha=0.5),font=3, cex=1.8,radius=1,border=F,main="Gráfico de Torta")
# col= cambia la gama de colores y alpha la transparencia. "rainbow" es una paleta preeterminada
# font= fuente_letra
# cex= tamaño_letra
# radius= tamaño de torta
# border = borde
# main= título
# Agrego etiquetas
etiquetas<-c("Mayo","Junio","Julio","Agosto","Septiembre") # define etiquetas
pct<-round(frec_catmonth/sum(frec_catmonth)*100) # calcula las frecuencias porcentuales
etiquetas<-paste(etiquetas,pct) # agrega los porcentajes a las etiquetas
etiquetas<-paste(etiquetas,"%",sep="") # agrega el simbolo % a los porcentajes
pie(frec_catmonth,labels =etiquetas,col=heat.colors(4,alpha=0.7)) # otra manera de asignar una paleta de colores
help(pie) # para ver qué otros parámetros recibe
3D
# Este tipo de gráficos requiere que se carguen librerías particulares (además de las incluídas en R)
# plotrix es una de ellas
library(plotrix)
# Si no la tienen instalada, primero hay que instalarla con el comando "install.packages("plotrix")"
# Ya se puede utilizar la funcion "pie3D" y darle como argumento la variable a graficar
pie3D(frec_catmonth, labels=etiquetas,labelcex=0.9)
pie3D(frec_catmonth,labels=etiquetas,explode=0.1,labelcex=0.9,radius=1.5,height=0.2,shade=0.6,col=terrain.colors(5,alpha=1), main='Qué gráfico fachero\n(no necesariamente útil)')
ANIDADOS
library(dplyr) # librería para manipular datos (muy útil - funciones concatenadas con "%>%")
## Warning: package 'dplyr' was built under R version 4.1.2
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# Cambia el nombre a campos categóricos de la variable Month
Month<-airquality%>%
pull(Month)%>%
plyr::mapvalues(c('5','6','7','8','9'),
c("Mayo","Junio","Julio","Agosto","Septiembre"))
# Creo una columna nueva, como para tener una variable categórica (que no tengo en la bd)
nueva_columna <- sample(rep( c("A","B"), 154 * c(0.4,0.6) ))
airquality$new_col <- nueva_columna
airquality$Month=Month
# Tabla del sector interior
interior<-airquality%>%
group_by(Month)%>%
tally( )%>%
mutate(porcent_abs=round(n/sum(n)*100,2))
exterior<-airquality%>%
group_by(Month,new_col)%>%
tally()%>%
mutate(porcent_rel=round(n/sum(n)*100,2))%>%
ungroup()%>%
mutate(porcent_abs=round(n/sum(n)*100,2))# Produce tabla del sector exterior
porcent_abs_ext=exterior$porcent_abs
tabla=table(exterior$Month)[order(unique(exterior$Month))]
#Establece los colores
colores=c("palegreen4","paleturquoise4","palevioletred4","salmon3","red")
col_int=rep_len(colores,length(airquality$Month))
col_ext=lapply(Map(rep,colores[seq_along(tabla)],tabla),
function(porcent_abs_ext){
al<-head(seq(0,1,length.out=length(porcent_abs_ext)+2L)[-1L],-1L)
Vectorize(adjustcolor)(porcent_abs_ext,alpha.f=al) } )
plot.new() # Borra gráficos anteriores
# Produce los diagramas de tortas
torta_ext= floating.pie(0.5,0.5,exterior$porcent_abs ,
radius =0.25 ,
border="gray45" ,
col= unlist(col_ext))
torta_int= floating.pie( 0.5,0.5,interior$porcent_abs ,
radius =0.2 ,
border="white" ,
col=col_int )
pie.labels( x =0.5 , y =0.5 , torta_ext ,
paste0 ( exterior$new_col, "\n" ,
exterior$porcent_rel , " % - " ,
exterior$n , " ind. " ) ,
minangle =0.2 , radius =0.27 ,
cex =0.6 , font=1)# Etiqueta las regiones exteriores
pie.labels( x =0.5 , y =0.5 , torta_int,
paste0( interior$Month,"\n" ,
interior$porcent_abs , " % - " ,
interior$n , " ind. " ) ,
minangle =0.2 , radius =0.09 , cex =0.6 , font=1) # Etiqueta las regiones interiores
barplot(airquality$Ozone, main = 'Concentración de ozono en el aire',
xlab = 'Niveles de ozono', col= 'blue',horiz = TRUE)
par(bg="mistyrose") # background
barplot(airquality$Ozone, main = 'Concentración de ozono en el aire',
xlab = 'Niveles de ozono', col= 'blue',horiz = FALSE)
barplot(table(airquality$Month), main = 'Categorías de mes',
xlab = 'Mes', col= 'blue',horiz = FALSE)
barplot(table(airquality$new_col,airquality$Month), main = 'Categorías de mes y A/B',
xlab = 'Mes + A/B', col= c('blue','darkblue'),horiz = FALSE)
barplot(table(airquality$new_col,airquality$Month)[,c(5,1,2,4,3)], main = 'Categorías de mes y A/B',
xlab = 'Mes + A/B', col= c('blue','darkblue'),horiz = FALSE) # cambiando el orden de las barras
legend("bottomright",cex=.8,title="Categoría",c("A","B"),fill=c('blue','darkblue'),horiz=F) # asigna leyendas en posición horizontal
Modelos<-2010:2016 # ingresa los modelos de los autos
Ventas<-c(2,3,7,4,9,0,5) # ingresa las frecuencias de las ventas de cada modelo
plot(Modelos,Ventas) # grafica los puntos
plot(Modelos,Ventas,type="h") # grafica bastones
plot(Modelos,Ventas,type="h",lty="twodash",lwd=4,col=heat.colors(9)) #cambia el estilo y groso de la línea, y el color
title("Ventas mensuales de una Agencia Chevrolet")
# Ahora armo el gráfico de partes - segmentos
plot(Modelos,Ventas)
segments(2010,0,2010,2) # agrega un segmento del punto (2010,0) al punto (2010,2)
segments(2010,0,2010,2,lwd=3,lty="dashed",col=1) # estilo rayado
segments(2011,0,2011,3,lwd=3,lty="dotted",col=2) # estilo punteado
segments(2012,0,2012,7,lwd=3,lty="solid",col=3) # estilo sólido
segments(2013,0,2013,4,lwd=3,lty="dotdash",col=4) # alterna estilos punteado y rayado
segments(2014,0,2014,9,lwd=3,lty="twodash",col=5) # estilo doble rayado
segments(2016,0,2016,5,lwd=3,lty="longdash",col=6) # estilo rayado largo
datos=airquality$Ozone
airquality$Ozone
## [1] 41 36 12 18 NA 28 23 19 8 NA 7 16 11 14 18 14 34 6
## [19] 30 11 1 11 4 32 NA NA NA 23 45 115 37 NA NA NA NA NA
## [37] NA 29 NA 71 39 NA NA 23 NA NA 21 37 20 12 13 NA NA NA
## [55] NA NA NA NA NA NA NA 135 49 32 NA 64 40 77 97 97 85 NA
## [73] 10 27 NA 7 48 35 61 79 63 16 NA NA 80 108 20 52 82 50
## [91] 64 59 39 9 16 78 35 66 122 89 110 NA NA 44 28 65 NA 22
## [109] 59 23 31 44 21 9 NA 45 168 73 NA 76 118 84 85 96 78 73
## [127] 91 47 32 20 23 21 24 44 21 28 9 13 46 18 13 24 16 13
## [145] 23 36 7 14 30 NA 14 18 20
stem(datos,scale=0.5) # da un histograma en el que se pueden apreciar los valores
##
## The decimal point is 1 digit(s) to the right of the |
##
## 0 | 146777899901112233334444666688889
## 2 | 0000111123333334478889001222455667799
## 4 | 014445567890299
## 6 | 13445613367889
## 8 | 0245591677
## 10 | 8058
## 12 | 25
## 14 |
## 16 | 8
stem(datos,scale=1)
##
## The decimal point is 1 digit(s) to the right of the |
##
## 0 | 1467778999
## 1 | 01112233334444666688889
## 2 | 0000111123333334478889
## 3 | 001222455667799
## 4 | 01444556789
## 5 | 0299
## 6 | 134456
## 7 | 13367889
## 8 | 024559
## 9 | 1677
## 10 | 8
## 11 | 058
## 12 | 2
## 13 | 5
## 14 |
## 15 |
## 16 | 8
hist(airquality$Ozone)
hist(airquality$Ozone, main = 'Concentración de ozono en el aire',xlab = 'Concentración de ozono',
ylab='Frecuencia',col='lightblue',density=18,angle=60,border="darkblue", breaks=30)
PESO2<-c(24.4, 23.6, 47.0, 24.0, 23.9, 41.0, 32.9, 22.4, 28.7, 31.4, 28.9, 51.2, 26.2, 58.5, 23.7, 25.5, 49.7, 39.6,42.5, 21.6, 38.0, 26.6, 20.4, 23.7, 21.4, 45.7, 51.3, 28.0, 26.9, 43.9,25.7,
28.2,36.8,27.3,33.8,23.5,33.1,37.5,33.2,36.8,29.2,30.6,28.1,23.5,19.8,23.6,26.0,
37.6,25.5,40.0,80.8,30.0,44.9,51.6,27.0,40.0,32.3,24.5,48.5,43.5,42.6,38.0,23.9,
52.0,55.2,48.0,50.5,19.0,32.0,33.5,38.0,24.5,31.5,21.2,19.9,26.7,23.0,46.3,38.2,
21.2,24.2,24.3,30.0,37.3,49.4,24.7,35.0,22.3,35.5,38.4,32.2,40.3,40.5,59.5,43.0,
20.3,22.0,58.0,37.5,41.3,18.5,19.1,32.5,34.6,29.6,33.8,42.3,31.0,23.4,21.5,21.3,39.5,
31.5,30.3,22.3,60.2,23.6,22.6,27.5,34.2,46.5,54.8,22.6,30.3,19.7,35.4,20.8,40.2,57.3,
45.5,28.4,34.6,26.4,35.0,23.7,26.4,52.4,32.6,41.1,23.3,38.2,25.5,
33.1,21.6,32.9,52.9,26.5,21.5,21.5,23.6)
R=quantile(PESO2,0.75)-quantile(PESO2,0.25) # calcula el rango intercuartil
n=length(PESO2) # guarda la cantidad de observaciones
h.FD=2*R*n^(-1/3) # sugerencia de Freedman-Diaconis para el ancho de clase
h.Scott=3.39*sd(PESO2)*n^(-1/3) # sugerencia de Scott para el ancho de clase
primero=floor(min(PESO2))-1 # guarda primer valor de la grilla
ultimo=ceiling(max(PESO2))+3 # guarda último valor de la grilla
grilla.FD=seq(primero,ultimo,h.FD) # defino primer valor de la grilla de Freedman Diaconis
grilla.Scott=seq(primero,ultimo,h.Scott)# defino primer valor de la grilla de Scott
hist(PESO2,breaks=grilla.FD) # cambia el ancho de las columnas
#----
a=length(grilla.FD)
pto.medio=rep(0,a-1) # inicia un vector
for (i in 1:length(grilla.FD)-1){
pto.medio[i]=(grilla.FD[i]+grilla.FD[i+1])/2} # calcula los puntos medios de los intervalos
alt.dens=hist(PESO2,breaks=grilla.FD,plot=F)$counts # calcula la altura correspondiente a cada punto medio
par(mfrow=c(1,2),oma=c(0,0,2,0)) # personaliza el espacio de gráfico
hist(PESO2,breaks=grilla.FD,col=heat.colors(a-1,alpha=1),
main="Freedman-Diaconis",
ylab="Frecuencia")
points(pto.medio,alt.dens,type="l",lwd=2) # superpone el polígono de frecuencias al histograma
#----
b=length(grilla.Scott)
pto.medio=rep(0,b-1)
for (i in 1:length(grilla.Scott)-1)
pto.medio[i]=(grilla.Scott[i]+grilla.Scott[i+1])/2
alt.dens=hist(PESO2,breaks=grilla.Scott,plot=F)$counts
hist(PESO2,breaks=grilla.Scott,col=heat.colors(b-1,alpha=1),main="Scott",ylab="Frecuencia")
points(pto.medio,alt.dens,type="l",lwd=2)
mtext("Polígonos de frecuencia", outer = TRUE, cex = 1.5)
par(bg="white")
dens=density(PESO2) # Kernel density estimation, es una manera no paramétrica de estimar la función de densidad de una variable aleatoria
plot(dens,main="Densidad de Peso",xlab="Peso",ylab="Densidad") # grafica la estimación de la densidad de la variable PESO
polygon(dens,lwd=2,col="lightblue",border="darkblue",main="Densidad de Peso") # cambia colores de relleno y borde
hist(PESO2,col=cm.colors(8,alpha=1),probability=T,breaks=grilla.Scott,main="Suavizado normal",ylab="Densidad") # histograma de densidad
xfit=seq(min(PESO2),max(PESO2),length=40) # arma una grilla de valores de datos
yfit=dnorm(xfit,mean=mean(PESO2),sd=sd(PESO2)) # realiza un suavizado normal de datos
lines(xfit,yfit,col="dodgerblue",lwd=2) # superpone el suavizado al histograma
par(mfrow=c(1,2)) # dividimos el área de gráficos en dos columnas
plot.ecdf(PESO2,col="blue",main="Peso",ylab="F(x)") # dibuja la función de distribución empírica
plot.ecdf(TALLA,col="red",main="Talla",ylab="F(x)")
par(mfrow=c(1,1)) # unifica la pantalla de gráficos
n=length(PESO)
plot(stepfun(1:(n-1),sort(PESO)),main="Función escalonada") # otra manera de definir y graficar la función acumulada
muestra= airquality$Ozone[!is.na(airquality$Ozone)]
summary(muestra)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.00 18.00 31.50 42.13 63.25 168.00
Md=median(muestra, na.rm=T) # variable con NAs... rompe la fc median
Q1=quantile(muestra,0.25)
Q3=quantile(muestra,0.75)
DI=Q3-Q1
Q3+1.5*DI
## 75%
## 131.125
Q1-1.5*DI
## 25%
## -49.875
Q3+3*DI
## 75%
## 199
Q1-3*DI
## 25%
## -117.75
# Valores de la función de graficación
q1= boxplot(muestra)$stats[2,1] #Q1
q3= boxplot(muestra)$stats[4,1] #Q3
print(paste('q1 es',q1))
## [1] "q1 es 18"
print(paste('q3 es',q3))
## [1] "q3 es 63.5"
par(mfrow=c(1,1),col.main="aquamarine4",adj=0) # cambia el color y la posición del título
boxplot(PESO,horizontal=T,boxcol=2, main= 'Boxplot horizontal') # colorea el borde de la caja
# Múltiples box plots (univariado!!)
#airquality[0:5,] # Selecciona primeras 5 filas y todas las columnas
#airquality[0:5,0:4] # Selecciona primeras 5 filas y las primeras 4 columnas
#airquality[,0:4] # Selecciona todas las filas y las primeras 4 columnas
boxplot(airquality[,0:4], main='Múltiples boxplot\nde distintas variables', col=c('red','blue','darkred','darkblue'))
par(oma=c(0,2,0,0))
# Múltiples box plots (Bivariado: Numérica + categórica)
boxplot(airquality$Ozone~airquality$Month, main='Boxplot de variable ozono\nen función del mes',
xlab= 'Concentración de ozono', ylab='',
col=c('red','blue','darkred','darkblue','darkgreen'),
horizontal=TRUE, las=1)
# Múltiples box plots (Numérica + categóricas)
cols= c('red','red','blue','blue','darkred','darkred','darkblue','darkblue','darkgreen','darkgreen')
cols2= c('darkred','darkblue')
par(oma=c(0,2,0,0))
boxplot(airquality$Ozone~airquality$new_col*airquality$Month, main='Boxplot de variable ozono\nen función del mes y A/B', xlab= 'Concentración de ozono', ylab='',col=cols, horizontal=TRUE, las=1)
par(oma=c(0,2,0,0))
boxplot(airquality$Ozone~airquality$new_col*airquality$Month, main='Boxplot de variable ozono\nen función del mes y A/B', xlab= 'Concentración de ozono', ylab='',col=cols2, horizontal=TRUE, notch=T, las=1)
## Warning in (function (z, notch = FALSE, width = NULL, varwidth = FALSE, : some
## notches went outside hinges ('box'): maybe set notch=FALSE